package com.foreveross.taskservice.core.domain.task;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.openkoala.koala.commons.domain.KoalaIDEntity;

import com.foreveross.taskservice.common.GlobalsConst;
import com.foreveross.taskservice.core.domain.task.assign.AssignBuildQueue;
import com.foreveross.taskservice.core.domain.task.assign.AssignDayType;
import com.foreveross.taskservice.infra.util.DateUtil;

/**
 * 抓取任务执行队列模板
 * <p>
 * 根据该模板生成<@link>TaskQueueEntity</link>
 * 
 * @author xiangsf 2013-2-17
 * 
 */
@javax.persistence.Table(name = "CRAWL_TASK_TEMPLATE")
@javax.persistence.Entity
public class TaskTemplateEntity  extends KoalaIDEntity{
	/**
	 * 
	 */
	private static final long serialVersionUID = -4448819408322145384L;
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id")
	private Long id;
	/**
	 * 任务名称
	 */
	@Column(name = "name")
	private String name;

	/**
	 * 起点城市区域码
	 */
	@Column(name = "area_code")
	private String areaCode;
	/**
	 * 起点城市区域名称
	 */
	@Column(name = "area_name")
	private String areaName;
	/**
	 * 起点城市
	 */
	@Column(name = "from_city")
	private String fromCity;

	@Column(name = "from_city_name")
	private String fromCityName;

	@Column(name = "to_city")
	private String toCity;

	@Column(name = "to_city_name")
	private String toCityName;

	@Column(name = "grab_channel_id")
	private Long grabChannelId;

	@Column(name = "grab_channel")
	private String grabChannel;

	/**
	 * 附加的hbase应用值，用于生成rowkey,以便于应用根据该值统计
	 * <p>实际上使用下面的"抓取渠道ID"也可，但基于应用已完成部分功能，补充上该值
	 */
	@Column(name = "attach_hbase_key")
	private String attachHbaseKey;
	
	@Column(name = "frequency")
	private int frequency;

	@Column(name = "next_grab_time")
	private Date nextGrabTime;

	@Column(name = "validity_to")
	private Date validityTo;

	@Column(name = "validity_from")
	private Date validityFrom;

	@Column(name = "status")
	private Integer status = GlobalsConst.DATA_STATUS_NORMAL;

	@Column(name = "priority")
	private int priority;

	@Column(name = "grab_scope_end")
	private int grabScopeEnd;

	@Column(name = "grab_scope_begin")
	private int grabScopeBegin;
	// 是否抓回程
	@Column(name = "is_return")
	private Integer isReturn = GlobalsConst.DATA_LOGIC_Y;

	@Column(name = "return_date_scope")
	private int returnDateScope;

	@Column(name = "user_id")
	private Long userId;

	@Column(name = "user_name")
	private String userName;
	
	@Column(name = "remark")
	private String remark;

	@Column(name = "create_time")
	private Date createTime = new Date();
	
	/**
	 * 是否属于国际航线
	 */
	@Column(name="IS_INTERNATIONAL")
	private Integer isInternational;
	
	@OneToMany(mappedBy="template",fetch=FetchType.LAZY,cascade={CascadeType.ALL} ) 
	private Set<TaskTemplateAssignDayEntity> assigndays=new HashSet<TaskTemplateAssignDayEntity>();

	public Set<TaskTemplateAssignDayEntity> getAssigndays() {
		return assigndays;
	}

	public void setAssigndays(Set<TaskTemplateAssignDayEntity> assigndays) {
		this.assigndays = assigndays;
	}

	public Integer getIsInternational() {
		return isInternational;
	}

	public void setIsInternational(Integer isInternational) {
		this.isInternational = isInternational;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getIsReturn() {
		return isReturn;
	}

	public void setIsReturn(Integer isReturn) {
		this.isReturn = isReturn;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getAreaCode() {
		return areaCode;
	}

	public void setAreaCode(String areaCode) {
		this.areaCode = areaCode;
	}

	public String getAreaName() {
		return areaName;
	}

	public void setAreaName(String areaName) {
		this.areaName = areaName;
	}

	public Long getGrabChannelId() {
		return grabChannelId;
	}

	public void setGrabChannelId(Long grabChannelId) {
		this.grabChannelId = grabChannelId;
	}

	public String getFromCity() {
		return fromCity;
	}

	public void setFromCity(String fromCity) {
		this.fromCity = fromCity;
	}

	public String getFromCityName() {
		return fromCityName;
	}

	public void setFromCityName(String fromCityName) {
		this.fromCityName = fromCityName;
	}

	public String getToCity() {
		return toCity;
	}

	public void setToCity(String toCity) {
		this.toCity = toCity;
	}

	public String getToCityName() {
		return toCityName;
	}

	public void setToCityName(String toCityName) {
		this.toCityName = toCityName;
	}

	public String getGrabChannel() {
		return grabChannel;
	}

	public void setGrabChannel(String grabChannel) {
		this.grabChannel = grabChannel;
	}

	public int getFrequency() {
		return frequency;
	}

	public void setFrequency(int frequency) {
		this.frequency = frequency;
	}

	public Date getNextGrabTime() {
		return nextGrabTime;
	}

	public String getAttachHbaseKey() {
		return attachHbaseKey;
	}

	public void setAttachHbaseKey(String attachHbaseKey) {
		this.attachHbaseKey = attachHbaseKey;
	}

	public void setNextGrabTime(Date nextGrabTime) {
		this.nextGrabTime = nextGrabTime;
	}

	public Date getValidityTo() {
		return validityTo;
	}

	public void setValidityTo(Date validityTo) {
		this.validityTo = validityTo;
	}

	public Date getValidityFrom() {
		return validityFrom;
	}

	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}

	public void setValidityFrom(Date validityFrom) {
		this.validityFrom = validityFrom;
	}

	public int getPriority() {
		return priority;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}

	public int getGrabScopeEnd() {
		return grabScopeEnd;
	}

	public void setGrabScopeEnd(int grabScopeEnd) {
		this.grabScopeEnd = grabScopeEnd;
	}

	public int getGrabScopeBegin() {
		return grabScopeBegin;
	}

	public void setGrabScopeBegin(int grabScopeBegin) {
		this.grabScopeBegin = grabScopeBegin;
	}


	public int getReturnDateScope() {
		return returnDateScope;
	}

	public void setReturnDateScope(int returnDateScope) {
		this.returnDateScope = returnDateScope;
	}

	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	@Override
	public String[] businessKeys() {
		return new String[]{getClass().getName()+id};
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("TaskTemplateEntity [id=");
		builder.append(id);
		builder.append(", name=");
		builder.append(name);
		builder.append(", areaCode=");
		builder.append(areaCode);
		builder.append(", areaName=");
		builder.append(areaName);
		builder.append(", fromCity=");
		builder.append(fromCity);
		builder.append(", fromCityName=");
		builder.append(fromCityName);
		builder.append(", toCity=");
		builder.append(toCity);
		builder.append(", toCityName=");
		builder.append(toCityName);
		builder.append(", grabChannelId=");
		builder.append(grabChannelId);
		builder.append(", grabChannel=");
		builder.append(grabChannel);
		builder.append(", attachHbaseKey=");
		builder.append(attachHbaseKey);
		builder.append(", frequency=");
		builder.append(frequency);
		builder.append(", nextGrabTime=");
		builder.append(nextGrabTime);
		builder.append(", validityTo=");
		builder.append(validityTo);
		builder.append(", validityFrom=");
		builder.append(validityFrom);
		builder.append(", status=");
		builder.append(status);
		builder.append(", priority=");
		builder.append(priority);
		builder.append(", grabScopeEnd=");
		builder.append(grabScopeEnd);
		builder.append(", grabScopeBegin=");
		builder.append(grabScopeBegin);
		builder.append(", isReturn=");
		builder.append(isReturn);
		builder.append(", returnDateScope=");
		builder.append(returnDateScope);
		builder.append(", userId=");
		builder.append(userId);
		builder.append(", userName=");
		builder.append(userName);
		builder.append(", remark=");
		builder.append(remark);
		builder.append(", createTime=");
		builder.append(createTime);
		builder.append(", isInternational=");
		builder.append(isInternational);
		builder.append(", assigndays=");
		builder.append(assigndays);
		builder.append("]");
		return builder.toString();
	}

	public List<TaskQueueRecordEntity> buildQueue(){
		List<TaskQueueRecordEntity> queues =new ArrayList<TaskQueueRecordEntity>();
		//未来连续天数
		if(this.getGrabScopeEnd()>0){
			for(int i=this.getGrabScopeBegin();i<this.getGrabScopeEnd()+1;i++){
				int end = this.getReturnDateScope()+i;
				queues.add(new TaskQueueRecordEntity(
						this.getFromCity(), this.getFromCityName(), this.getToCity(), this.getToCityName(),
						DateUtil.getDateAfter(i), 
						DateUtil.getDateAfter(end),
								this.getIsInternational()==null?0:this.getIsInternational().intValue(), this.getIsReturn()==null?0:this.getIsReturn(), 
										this.getGrabChannelId(), this.getGrabChannel(), this.getAreaCode(), this.getAreaName(), this.getAttachHbaseKey(), this.getPriority()));
			}
		}
		List<TaskTemplateAssignDayEntity> list = listAllAssignDays();
		//往返扩展配置天数
		if(list!=null && !list.isEmpty()){//指定
			for(TaskTemplateAssignDayEntity ta : list){
				AssignBuildQueue buildQueueBean = AssignDayType.assignBean(ta.getAssignDayType());
				queues.addAll(buildQueueBean.build(ta));
			}
		}
		return queues;
	}
	
	private List<TaskTemplateAssignDayEntity> listAllAssignDays(){
		return this.getRepository().createCriteriaQuery(TaskTemplateAssignDayEntity.class)
		.eq("template", this).list();
	}
}
